package com.itheima.service.mongo.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.itheima.domain.mongo.*;
import com.itheima.domain.vo.PageBeanVo;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.List;

@Service // dubbo的
public class MovementServiceImpl implements MovementService {

    @Autowired
    MongoTemplate mongoTemplate;

    @Autowired
    private IdService idService;

    @Override
    public void saveMovement(Movement movement) {
        // 0.生成动态大数据pid
        Long pid = idService.getNextId(ConstantUtil.MOVEMENT_ID);
        movement.setPid(pid);

        // 1.将动态保存到详情表，并返回动态id
        mongoTemplate.save(movement);
        ObjectId movementId = movement.getId();

        // 2.将动态id保存到个人动态表
        MyMovement myMovement = new MyMovement();
        myMovement.setPublishId(movementId); // 指定动态id
        myMovement.setCreated(System.currentTimeMillis());// 指定发布时间
        mongoTemplate.save(myMovement, ConstantUtil.MOVEMENT_MINE + movement.getUserId()); // 保存到当前用户的动态表中

        // 3.查询当前用户好友列表
        // 3-1 查询对象
        Query query = new Query(Criteria.where("userId").is(movement.getUserId()));
        // 3-2 条件查询
        List<Friend> friendList = mongoTemplate.find(query, Friend.class);

        // 4.遍历好友，将动态id保存到朋友的好友动态表中
        if (friendList != null && friendList.size() > 0) {
            for (Friend friend : friendList) {
                // 获取好友id
                Long friendId = friend.getFriendId();
                // 将动态id保存到朋友的好友动态表中
                FriendMovement friendMovement = new FriendMovement();
                friendMovement.setPublishId(movementId); // 指定动态id
                friendMovement.setUserId(movement.getUserId()); // 指定发布动态用户
                friendMovement.setCreated(System.currentTimeMillis()); // 指定发布时间

                mongoTemplate.save(friendMovement, ConstantUtil.MOVEMENT_FRIEND + friendId);

            }
        }

    }

    @Override
    public PageBeanVo findMyMovementByPage(Integer pageNum, Integer pageSize, Long userId) {
        // 1.以用户id和分页条件查询我的动态表
        // 1-1 创建查询对象
        Integer index = (pageNum - 1) * pageSize;
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created"))) // 排序
                .skip(index).limit(pageSize);// 分页
        // 1-2 查询我的动态表
        List<MyMovement> myMovementList = mongoTemplate.find(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);

        // 2.遍历我的动态列表，根据动态id，查询并封装动态详情
        // 2-1 详情列表
        List<Movement> movementList = new ArrayList<>();
        // 2-2 审核失败计数器
        long shiBaiCount = 0;
        // 2-3 遍历
        if (CollectionUtil.isNotEmpty(myMovementList)) {
            for (MyMovement myMovement : myMovementList) {
                // 获取动态id
                ObjectId movementId = myMovement.getPublishId();
                // 根据动态id，查询并封装动态详情
                Movement movement = mongoTemplate.findById(movementId, Movement.class);
                // 判断是否审核通过
                if (movement.getState() == 1) {
                    movementList.add(movement);
                } else {
                    shiBaiCount++;
                }
            }
        }
        // 3.返回并封装分页对象
        // 3-1 计算出我的动态总记录数
        long counts = mongoTemplate.count(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);
        // 3-2 减去失败的数量
        counts = counts - shiBaiCount;
        // 3-3 返回
        return new PageBeanVo(pageNum, pageSize, counts, movementList);
    }

    @Override
    public PageBeanVo findFriendMovementByPage(Integer pageNum, Integer pageSize, Long userId) {
        // 1.以用户id和分页条件查询好友动态表
        // 1-1 创建查询对象
        Integer index = (pageNum - 1) * pageSize;
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created"))) // 排序
                .skip(index).limit(pageSize); // 分页
        // 1-2 查询
        List<FriendMovement> friendMovementList = mongoTemplate.find(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);

        // 2.遍历好友列表，获取动态id，查询动态详情
        // 2-1 声明动态详情集合
        List<Movement> movementList = new ArrayList<>();
        // 2-2 声明审核失败计数器
        long shiBaiCount = 0;
        // 2-3遍历好友列表
        if (CollectionUtil.isNotEmpty(friendMovementList)) {
            for (FriendMovement friendMovement : friendMovementList) {
                // 2-4 获取动态id
                ObjectId movementId = friendMovement.getPublishId();
                // 2-5 查询动态详情
                Movement movement = mongoTemplate.findById(movementId, Movement.class);
                // 2-6 判断封装
                if (movement.getState() == 1) {
                    movementList.add(movement);
                } else {
                    shiBaiCount++;
                }

            }
        }

        // 3.封装并返回分页对象
        // 3-1 总记录数
        long count = mongoTemplate.count(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);
        count = count - shiBaiCount;
        // 3-2 返回
        return new PageBeanVo(pageNum, pageSize, count, movementList);
    }

    @Override
    public PageBeanVo findRecommendMovementByPage(Integer pageNum, Integer pageSize, Long userId) {
        // 1.组装条件
        Integer index = (pageNum - 1) * pageSize;
        Query query = new Query(
                Criteria.where("userId").is(userId)
        ).with(Sort.by(Sort.Order.desc("created")))
                .skip(index).limit(pageSize);

        // 2.查询推荐表
        List<RecommendMovement> recommendMovementList = mongoTemplate.find(query, RecommendMovement.class);

        // 3.遍历推荐根据动态id查询详情
        List<Movement> movementList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(recommendMovementList)) {
            for (RecommendMovement recommendMovement : recommendMovementList) {
                // 获取动态id
                ObjectId movementId = recommendMovement.getPublishId();
                // 查询动态详情
                Movement movement = mongoTemplate.findById(movementId, Movement.class);

                movementList.add(movement);
            }
        }

        // 4.统计总记录数
        long count = mongoTemplate.count(query, RecommendMovement.class);

        // 5.封装分页对象
        return new PageBeanVo(pageNum, pageSize, count, movementList);
    }

    // 根据主键查询动态
    @Override
    public Movement findMovementById(String movementId) {
        return mongoTemplate.findById(new ObjectId(movementId), Movement.class);
    }

    @Override
    public PageBeanVo findMovementByCondition(Long uid, Integer state, Integer pageNum, Integer pageSize) {
        // 1.组装查询条件
        Query query = new Query().with(Sort.by(Sort.Order.desc("created"))).skip((pageNum - 1) * pageSize).limit(pageSize);
        if (uid != null) { // 用户id条件
            query.addCriteria(Criteria.where("userId").is(uid));
        }
        if (state != null) {// 审核状态条件
            query.addCriteria(Criteria.where("state").is(state));
        }
        // 2.查询list
        List<Movement> movementList = mongoTemplate.find(query, Movement.class);
        // 3.查询count
        long count = mongoTemplate.count(query, Movement.class);
        // 4.返回分页结果
        return new PageBeanVo(pageNum, pageSize, count, movementList);
    }

    @Override
    public void updateMovementState(Movement movement) {
        mongoTemplate.save(movement);
    }
}
